Promise = global.Promise || require('es6-promise').Promise;
var amqp = require('amqp-connection-manager');

var Config = require('config');
var queueConf = Config.get('message_queue');
var DEFAULT_QUEUE = 'amqp://' + queueConf.username + ':' + queueConf.password + '@' + queueConf.server + '/' + queueConf.virtual_hose;

var parse = require('../algo/rtcm/parse_distrib.js');

var request = require('request');

function mappping(logJSON) {
    var algoIn = logJSON.obsR,
        algoOut = logJSON.posR;

    var webIn = {
        abserror: {
            hor: 1,
            ver: 1
        },
        accinfo: {
            hacc: algoOut.dH,
            vacc: algoOut.dV
        },
        alarmthreshold: {
            // from configuration
            // TODO provide storage for conf
        },
        dopinfo: {
            hdop: algoOut.HDOP,
            vdop: algoOut.VDOP,
            pdop: algoOut.PDOP
        },
        obsinfo: [],
        //     {
        //         cn: algoIn.S,
        //         d: algoIn.D,
        //         l: algoIn.L,
        //         p: algoIn.P,
        //         prn: algoIn.satid,
        //         residual: algoIn.resp,
        //         sys: 0, // TODO frontend signal -> sys
        //         svh: algoIn.svh, // health
        //         tow: algoIn.tow, // TODO algo +0 UNIX time, second for week
        //         week: algoIn.week, // TODO algo
        //         ion: 0 // ??? // TODO 0 for placeholder
        //     }
        // ],
        plinfo: {
            hpl: algoOut.HPL,
            vpl: algoOut.VPL
        },
        posinfo: {
            alt: algoOut.H,
            lat: algoOut.Lat,
            lon: algoOut.Lon,
            rura: -1,
            type: (algoOut.navsys.length > 1) ? 3 : algoOut.navsys[0],
            udre: -1,
            utc: algoOut.time,
        },
        satnum: { // TODO frontend
            bdsatnum: 0, //TODO
            glsatnum: 0,//TODO
            gpssatnum: 0 //TODO
        },
        satpos: {
            bdsatpos: []
        },

        station: "0"
    }

    for (var i in algoIn) {
        var obs = algoIn[i];
        var obsinfo = {
            cn: obs.S,
            d: obs.D,
            l: obs.L,
            p: obs.P,
            prn: obs.satid,
            residual: obs.resp,
            sys: 0, // TODO frontend signal -> sys
            svh: obs.svh, // health
            tow: obs.tow, // TODO algo +0 UNIX time, second for week
            week: obs.week, // TODO algo
            ion: 0 // ??? // TODO 0 for placeholder
        }
        var bdsatpos = {
            az: obs.Azi,
            el: obs.Ele,
            prn: obs.satid
        }
        webIn.obsinfo.push(obsinfo);
        webIn.satpos.bdsatpos.push(bdsatpos);
    }
    return webIn;
}

// Handle an incomming message.
var onMessage = function (data) {
    // TODO check the hash value of this package

    var message = JSON.parse(data.content.toString());
    var buffer = new Buffer(message.data, 'base64');
    var id = 0;
    var results = parse.datatype(id, buffer);
    results.forEach(function (sta_data) {
        var options = {
            headers: {"Connection": "close"},
            url: 'http://127.0.0.1:3001/?sta_id=' + id,
            method: 'POST',
            json: true,
            body: sta_data
        };

        request(options, function (error, response, data) {
                if (error) {
                    console.log(error);
                } else {
                    try {
                        //posStatistic(data.sta_id,data.posR);
                        // console.log("lala:" + data.posR.time, data.posR.Lat, data.posR.Lon, data.posR.H);
                        // console.log("lala:");
                        console.log({
                            algoIn: data,
                            algoOut: mappping(data)
                        });
                    } catch (err) {
                        console.log(err.message);
                    }
                }
            }
        );
    })
    channelWrapper.ack(data);
}

// Create a connetion manager
var connection = amqp.connect([DEFAULT_QUEUE], {json: true});
connection.on('connect', function () {
    console.log('Connected!');
});
connection.on('disconnect', function (params) {
    console.log('Disconnected.', params.err.stack);
});

// Set up a channel listening for messages in the queue.
var channelWrapper = connection.createChannel({
    setup: function (channel) {
        // `channel` here is a regular amqplib `ConfirmChannel`.
        return Promise.all([
            channel.assertQueue(queueConf.name, {durable: false}),
            channel.consume(queueConf.name, onMessage)
        ]);
    }
});

channelWrapper.waitForConnect()
    .then(function () {
        console.log("Listening for messages");
    });